package com.example.docmanagement.dto.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 分类响应 DTO
 * 返回分类的详细信息
 * 支持树形结构（通过children字段嵌套子分类）
 * 注：空字段不会在JSON响应中出现
 * 
 * 示例 JSON（树形结构）:
 * {
 * "id": 1,
 * "name": "编程语言",
 * "slug": "programming-languages",
 * "description": "各种编程语言的学习资料",
 * "icon": "code",
 * "parentId": null,
 * "sortOrder": 1,
 * "docCount": 156,
 * "isActive": true,
 * "createdAt": "2024-01-01T00:00:00",
 * "updatedAt": "2024-01-20T10:30:00",
 * "children": [
 * {
 * "id": 2,
 * "name": "Java",
 * "slug": "java",
 * "description": "Java编程相关文档",
 * "icon": "java-logo",
 * "parentId": 1,
 * "sortOrder": 1,
 * "docCount": 89,
 * "isActive": true,
 * "createdAt": "2024-01-02T00:00:00",
 * "updatedAt": "2024-01-15T08:00:00",
 * "children": []
 * }
 * ]
 * }
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) // 空字段不序列化
@Schema(description = "分类响应数据")
public class CategoryResponse {

    /**
     * 用于 JPQL 构造函数表达式的构造函数
     * 参数顺序必须与查询中的 SELECT 字段顺序完全一致
     */
    public CategoryResponse(Long id, String name, String slug, String description, String icon,
            Long parentId, Integer sortOrder, Integer docCount, Boolean isActive,
            LocalDateTime createdAt, LocalDateTime updatedAt) {
        this.id = id;
        this.name = name;
        this.slug = slug;
        this.description = description;
        this.icon = icon;
        this.parentId = parentId;
        this.sortOrder = sortOrder;
        this.docCount = docCount;
        this.isActive = isActive;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
        this.children = null; // 扁平列表不包含子分类
    }

    /**
     * 分类ID
     * 数据库自增主键
     * 示例：1
     */
    @Schema(description = "分类ID", example = "1")
    private Long id;

    /**
     * 分类名称
     * 示例："编程语言"、"Java"
     */
    @Schema(description = "分类名称", example = "编程语言")
    private String name;

    /**
     * 分类唯一标识符
     * 用于生成友好的URL
     * 示例:"programming-languages"、"java"
     */
    @Schema(description = "分类唯一标识符(slug)", example = "programming-languages")
    private String slug;

    /**
     * 分类描述
     * 详细说明该分类的用途和内容
     * 示例："包含Java、Python、JavaScript等主流编程语言的学习资料"
     */
    @Schema(description = "分类描述", example = "包含Java、Python、JavaScript等主流编程语言的学习资料")
    private String description;

    /**
     * 分类图标
     * 图标名称或URL，用于前端显示
     * 示例："code"、"java-logo"、"https://example.com/icons/java.svg"
     */
    @Schema(description = "分类图标", example = "code")
    private String icon;

    /**
     * 父分类ID
     * 指向父分类的主键
     * null表示顶级分类
     * 示例：1（表示这是ID为1的分类的子分类）
     */
    @Schema(description = "父分类ID（null表示顶级分类）", example = "1")
    private Long parentId;

    /**
     * 排序顺序
     * 用于控制同级分类的显示顺序
     * 数值越小越靠前
     * 示例：1, 2, 3...
     */
    @Schema(description = "排序顺序", example = "1")
    private Integer sortOrder;

    /**
     * 文档数量
     * 该分类下的文档总数（包括子分类）
     * 示例：156
     */
    @Schema(description = "文档数量（含子分类）", example = "156")
    private Integer docCount;

    /**
     * 是否启用
     * true: 启用状态，前端可显示
     * false: 禁用状态，前端不显示
     */
    @Schema(description = "是否启用", example = "true")
    private Boolean isActive;

    /**
     * 创建时间
     * 分类首次创建的时间戳
     * 格式：ISO 8601
     * 示例："2024-01-01T00:00:00"
     */
    @Schema(description = "创建时间", example = "2024-01-01T00:00:00", type = "string", format = "date-time")
    private LocalDateTime createdAt;

    /**
     * 最后更新时间
     * 分类最近一次修改的时间戳
     * 格式：ISO 8601
     * 示例："2024-01-20T10:30:00"
     */
    @Schema(description = "最后更新时间", example = "2024-01-20T10:30:00", type = "string", format = "date-time")
    private LocalDateTime updatedAt;

    /**
     * 子分类列表（树形结构）
     * 递归包含所有子分类及其子分类
     * 空列表或null表示没有子分类
     * 在平铺模式(flat=true)查询时此字段为null
     * 示例：[{子分类1}, {子分类2}, ...]
     */
    @Schema(description = "子分类列表（树形结构）")
    private List<CategoryResponse> children;
}
